package top.lingkang.ciyuanwaf.controller;

import cn.hutool.core.codec.Base64Decoder;
import cn.hutool.core.util.StrUtil;
import org.noear.solon.annotation.Controller;
import org.noear.solon.annotation.Inject;
import org.noear.solon.annotation.Mapping;
import org.noear.solon.core.handle.Context;
import org.noear.solon.core.handle.MethodType;
import org.noear.solon.core.handle.ModelAndView;
import top.lingkang.ciyuanwaf.dao.SettingDao;
import top.lingkang.ciyuanwaf.dto.ResponseResult;
import top.lingkang.ciyuanwaf.entity.SettingEntity;
import top.lingkang.ciyuanwaf.utils.CheckUtils;
import top.lingkang.ciyuanwaf.vo.LogListVO;

import java.io.File;
import java.io.RandomAccessFile;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @author lingkang
 * created by 2023/11/27
 */
@Controller
@Mapping("/nginx/log")
public class NginxLogController {
    @Inject
    private SettingDao settingDao;

    @Mapping(value = "/index", method = MethodType.GET)
    public Object index() {
        SettingEntity setting = settingDao.getSetting();
        if (!"true".equals(setting.getIsInit()))
            return new ResponseResult<>().fail("还未绑定nginx");
        String path = null;
        if (StrUtil.isNotBlank(setting.getLogPath())) {
            path = setting.getLogPath();
        }
        ModelAndView view = new ModelAndView("log.ftl");
        List<LogListVO> list = new ArrayList<>();
        view.put("path", path);
        if (path != null) {
            File files = new File(path);
            if (files.exists())
                for (File file : files.listFiles()) {
                    LogListVO vo = new LogListVO();
                    vo.setName(file.getAbsolutePath());
                    vo.setSize(file.length());
                    vo.setLastUpdateTime(new Date(file.lastModified()));
                    list.add(vo);
                }
        }
        view.put("list", list);
        return view;
    }

    @Mapping(value = "/updatePath", method = MethodType.POST)
    public Object updatePath(String path) {
        CheckUtils.checkNotEmpty(path, "日志路径");

        File file = new File(path);
        if (!file.exists())
            return new ResponseResult<>().fail("不存在的路径：" + file.getAbsolutePath());
        if (!file.isDirectory())
            return new ResponseResult<>().fail("不是目录路径：" + file.getAbsolutePath());

        SettingEntity setting = settingDao.getSetting();
        setting.setLogPath(file.getAbsolutePath());
        settingDao.saveOrUpdate(setting);
        return new ResponseResult<>("更新成功！");
    }

    @Mapping(value = "/download", method = MethodType.GET)
    public void download(String name, Context context) throws Exception {
        CheckUtils.checkNotEmpty(name, "文件名");
        SettingEntity setting = settingDao.getSetting();
        if (!"true".equals(setting.getIsInit())) {
            context.outputAsJson(new ResponseResult<>().fail("还未绑定nginx").toJsonString());
            return;
        }
        name = Base64Decoder.decodeStr(name);
        File file = new File(name);
        if (!file.exists()) {
            context.outputAsJson(new ResponseResult<>().fail("文件不存在：" + name).toJsonString());
            return;
        }
        context.outputAsFile(file);
    }

    @Mapping(value = "/see", method = MethodType.GET)
    public Object see(String name) {
        CheckUtils.checkNotEmpty(name, "日志名称");
        SettingEntity setting = settingDao.getSetting();
        if (!"true".equals(setting.getIsInit()))
            return new ResponseResult<>().fail("还未绑定nginx");
        ModelAndView view = new ModelAndView("logSee.ftl");
        view.put("name", name);
        view.put("realName", Base64Decoder.decodeStr(name));
        return view;
    }

    @Mapping(value = "/see", method = MethodType.POST)
    public Object see(String name, Integer line) {
        CheckUtils.checkNotEmpty(name, "日志名称");
        name = Base64Decoder.decodeStr(name);
        File file = new File(name);
        if (!file.exists())
            return new ResponseResult<>().fail("文件不存在：" + file.getAbsolutePath());

        if (line == null || line < 100 || line > 1111) {
            line = 200;
        }

        try (RandomAccessFile accessFile = new RandomAccessFile(file, "r")) {
            long position = file.length() - 1;
            StringBuffer buffer = new StringBuffer();
            while (position >= 0) {
                accessFile.seek(position);
                char ch = (char) accessFile.read();
                if (ch == '\n') {
                    line--;
                }
                buffer.append(ch);
                position--;
                if (line == 0)
                    break;
            }
            return new ResponseResult<>().setData(buffer);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

}
